using System;
using System.Data;
using System.Xml;

using OR.Reuse.Persistence;

using Derived = OR.Lazarus.Library.DataTier.Source;

namespace OR.Lazarus.Library.DataTier.Source.Lazarus
{
	/// <summary>
	/// Defines a class, with fields and methods.
	/// </summary>
   public class ObjectDetail : EntityBase
   {
		protected System.String mName;
		protected string mAlias;
		protected string mFriendlyName;
		protected string mLogicalName;
		protected string mFilegroup;
		protected string mDBTable;
		protected string mTitleField;
		protected string mTypeTable;
		protected string mTypeField;
		protected string mDescription;
	
		protected Derived.ImplementCollection mImplements;
		protected Derived.AttributeFlagCollection mFlags;
		protected Derived.FieldCollection mFields;
		protected Derived.MethodCollection mMethods;
		protected Derived.PermissionCollection mPermissions;
		protected Derived.CollectionCollection mCollections;
		protected Derived.DataRowCollection mInitialData;

		public ObjectDetail()
		{
			mImplements = new Derived.ImplementCollection();
			mImplements.ParentEntity = this;
			mFlags = new Derived.AttributeFlagCollection();
			mFlags.ParentEntity = this;
			mFields = new Derived.FieldCollection();
			mFields.ParentEntity = this;
			mMethods = new Derived.MethodCollection();
			mMethods.ParentEntity = this;
			mPermissions = new Derived.PermissionCollection();
			mPermissions.ParentEntity = this;
			mCollections = new Derived.CollectionCollection();
			mCollections.ParentEntity = this;
			mInitialData = new Derived.DataRowCollection();
			mInitialData.ParentEntity = this;
	
		}
	
		/// <summary>
		/// Specifies a unique name for the entity.
		/// </summary>
		public System.String Name
		{
			get
			{
				return ( mName );
			}
			set
			{
				mName = value;
			}
		}

		/// <summary>
		/// The object's alias represents its name for use in XML representations.  It defaults to the lowercase representation of the Name.
		/// </summary>
		public string Alias
		{
			get
			{
				return ( mAlias );
			}
			set
			{
				mAlias = value;
			}
		}

		/// <summary>
		/// The Friendly Name of the object is it's real-world name.  Spaces and other punctuation is allowed, if applicable.  For example, the FriendlyName of the [DefaultSettings] object would be "Default Settings".
		/// </summary>
		public string FriendlyName
		{
			get
			{
				return ( mFriendlyName );
			}
			set
			{
				mFriendlyName = value;
			}
		}

		/// <summary>
		/// The object's Logical Name is for use in object-oriented and object-based scenarios.  This would be used to identify the object in an ORM, UML or C# object model, for example.  The LogicalName defaults to the Name.
		/// </summary>
		public string LogicalName
		{
			get
			{
				return ( mLogicalName );
			}
			set
			{
				mLogicalName = value;
			}
		}

		/// <summary>
		/// The Filegroup specifies the physical storage container for the object.  It is generally used in Relational Database scenarios.
		/// </summary>
		public string Filegroup
		{
			get
			{
				return ( mFilegroup );
			}
			set
			{
				mFilegroup = value;
			}
		}

		/// <summary>
		/// The DBTable specifies the table name that an object is associated with.  This defaults to "tbl" plus the name of the object.
		/// </summary>
		public string DBTable
		{
			get
			{
				return ( mDBTable );
			}
			set
			{
				mDBTable = value;
			}
		}

		/// <summary>
		/// Defines the column of the object that is used to identify a row to the user.  For example, the Company object might use the Name field as it's TitleField.
		/// </summary>
		public string TitleField
		{
			get
			{
				return ( mTitleField );
			}
			set
			{
				mTitleField = value;
			}
		}

		/// <summary>
		/// For objects that are part of Generalization Hierarchies, this specifies the table that contains the generalization hierarchy map.  This value is only valid for objects involved in a Generalization Hierarchy.
		/// </summary>
		public string TypeTable
		{
			get
			{
				return ( mTypeTable );
			}
			set
			{
				mTypeTable = value;
			}
		}

		/// <summary>
		/// For objects that are part of Generalization Hierarchies, this specifies the table that contains the generalization hierarchy map.
		/// </summary>
		public string TypeField
		{
			get
			{
				return ( mTypeField );
			}
			set
			{
				mTypeField = value;
			}
		}

		/// <summary>
		/// Provides a long-text description for the entity.
		/// </summary>
		public string Description
		{
			get
			{
				return ( mDescription );
			}
			set
			{
				mDescription = value;
			}
		}

		public Derived.ImplementCollection Implements
		{
			get
			{
				return ( mImplements );
			}
			set
			{
				mImplements = value;
			}
		}

		public Derived.AttributeFlagCollection Flags
		{
			get
			{
				return ( mFlags );
			}
			set
			{
				mFlags = value;
			}
		}

		public Derived.FieldCollection Fields
		{
			get
			{
				return ( mFields );
			}
			set
			{
				mFields = value;
			}
		}

		public Derived.MethodCollection Methods
		{
			get
			{
				return ( mMethods );
			}
			set
			{
				mMethods = value;
			}
		}

		public Derived.PermissionCollection Permissions
		{
			get
			{
				return ( mPermissions );
			}
			set
			{
				mPermissions = value;
			}
		}

		public Derived.CollectionCollection Collections
		{
			get
			{
				return ( mCollections );
			}
			set
			{
				mCollections = value;
			}
		}

		public Derived.DataRowCollection InitialData
		{
			get
			{
				return ( mInitialData );
			}
			set
			{
				mInitialData = value;
			}
		}

		public override void LoadXml( XmlElement pSource )
		{
			// Scalar Values
			mName = DataUtility.GetString( pSource, "name" );
			mAlias = DataUtility.GetString( pSource, "alias" );
			mFriendlyName = DataUtility.GetString( pSource, "friendly-name" );
			mLogicalName = DataUtility.GetString( pSource, "logical-name" );
			mFilegroup = DataUtility.GetString( pSource, "filegroup" );
			mDBTable = DataUtility.GetString( pSource, "db-table" );
			mTitleField = DataUtility.GetString( pSource, "title-field" );
			mTypeTable = DataUtility.GetString( pSource, "type-table" );
			mTypeField = DataUtility.GetString( pSource, "type-field" );
			XmlElement vDescription = ( XmlElement )pSource.SelectSingleNode( "lz:description", PersistenceConfig.Namespaces );
			
			if ( vDescription != null )
			{
				mDescription = vDescription.InnerText;
			}
			
			XmlElement vImplements = ( XmlElement )pSource.SelectSingleNode( "lz:implements", PersistenceConfig.Namespaces );
			
			if ( vImplements != null )
			{
				mImplements.LoadXml( vImplements );
			}
			XmlElement vFlags = ( XmlElement )pSource.SelectSingleNode( "lz:flags", PersistenceConfig.Namespaces );
			
			if ( vFlags != null )
			{
				mFlags.LoadXml( vFlags );
			}
			XmlElement vFields = ( XmlElement )pSource.SelectSingleNode( "lz:fields", PersistenceConfig.Namespaces );
			
			if ( vFields != null )
			{
				mFields.LoadXml( vFields );
			}
			XmlElement vMethods = ( XmlElement )pSource.SelectSingleNode( "lz:methods", PersistenceConfig.Namespaces );
			
			if ( vMethods != null )
			{
				mMethods.LoadXml( vMethods );
			}
			XmlElement vPermissions = ( XmlElement )pSource.SelectSingleNode( "lz:permissions", PersistenceConfig.Namespaces );
			
			if ( vPermissions != null )
			{
				mPermissions.LoadXml( vPermissions );
			}
			XmlElement vCollections = ( XmlElement )pSource.SelectSingleNode( "lz:collections", PersistenceConfig.Namespaces );
			
			if ( vCollections != null )
			{
				mCollections.LoadXml( vCollections );
			}
			XmlElement vInitialData = ( XmlElement )pSource.SelectSingleNode( "lz:initial-data", PersistenceConfig.Namespaces );
			
			if ( vInitialData != null )
			{
				mInitialData.LoadXml( vInitialData );
			}
		}
		
		public override XmlElement SaveXml( XmlDocument p_docContext )
		{
			XmlElement vNewElement	= p_docContext.CreateElement( "lz", "object", "http://schemas.icitadel.com/Lazarus/Source.xsd" );

			// Scalar Values
			if ( !String.IsNullOrEmpty( mName ) )
			{
				vNewElement.SetAttribute( "name", mName );
			}
					
			if ( !String.IsNullOrEmpty( mAlias ) )
			{
				vNewElement.SetAttribute( "alias", mAlias );
			}
					
			if ( !String.IsNullOrEmpty( mFriendlyName ) )
			{
				vNewElement.SetAttribute( "friendly-name", mFriendlyName );
			}
					
			if ( !String.IsNullOrEmpty( mLogicalName ) )
			{
				vNewElement.SetAttribute( "logical-name", mLogicalName );
			}
					
			if ( !String.IsNullOrEmpty( mFilegroup ) )
			{
				vNewElement.SetAttribute( "filegroup", mFilegroup );
			}
					
			if ( !String.IsNullOrEmpty( mDBTable ) )
			{
				vNewElement.SetAttribute( "db-table", mDBTable );
			}
					
			if ( !String.IsNullOrEmpty( mTitleField ) )
			{
				vNewElement.SetAttribute( "title-field", mTitleField );
			}
					
			if ( !String.IsNullOrEmpty( mTypeTable ) )
			{
				vNewElement.SetAttribute( "type-table", mTypeTable );
			}
					
			if ( !String.IsNullOrEmpty( mTypeField ) )
			{
				vNewElement.SetAttribute( "type-field", mTypeField );
			}
					
			if ( !String.IsNullOrEmpty( mDescription ) )
			{
				XmlElement	vDescription = p_docContext.CreateElement( "lz", "description", "http://schemas.icitadel.com/Lazarus/Source.xsd" );
				vDescription.InnerText = mDescription;
				vNewElement.AppendChild( vDescription );
			}
					

			// Collections
			
			XmlElement	vCollection	= null;
			
			vCollection = mImplements.SaveXml( p_docContext );
			if ( vCollection != null )
			{
				vNewElement.AppendChild( vCollection );
			}
			
			vCollection = mFlags.SaveXml( p_docContext );
			if ( vCollection != null )
			{
				vNewElement.AppendChild( vCollection );
			}
			
			vCollection = mFields.SaveXml( p_docContext );
			if ( vCollection != null )
			{
				vNewElement.AppendChild( vCollection );
			}
			
			vCollection = mMethods.SaveXml( p_docContext );
			if ( vCollection != null )
			{
				vNewElement.AppendChild( vCollection );
			}
			
			vCollection = mPermissions.SaveXml( p_docContext );
			if ( vCollection != null )
			{
				vNewElement.AppendChild( vCollection );
			}
			
			vCollection = mCollections.SaveXml( p_docContext );
			if ( vCollection != null )
			{
				vNewElement.AppendChild( vCollection );
			}
			
			vCollection = mInitialData.SaveXml( p_docContext );
			if ( vCollection != null )
			{
				vNewElement.AppendChild( vCollection );
			}

			return ( vNewElement );
		}

		public virtual object Clone()
		{
			Derived.ObjectDetail v_oReturn = new Derived.ObjectDetail();
			
			v_oReturn.Name = mName;
			v_oReturn.Alias = mAlias;
			v_oReturn.FriendlyName = mFriendlyName;
			v_oReturn.LogicalName = mLogicalName;
			v_oReturn.Filegroup = mFilegroup;
			v_oReturn.DBTable = mDBTable;
			v_oReturn.TitleField = mTitleField;
			v_oReturn.TypeTable = mTypeTable;
			v_oReturn.TypeField = mTypeField;
			v_oReturn.Description = mDescription;
			
			// FK Values

			// Collections

			foreach ( Derived.ImplementDetail vDetail in mImplements )
			{
				v_oReturn.Implements.Add( vDetail.CloneTyped() );
			}

			foreach ( Derived.AttributeFlagDetail vDetail in mFlags )
			{
				v_oReturn.Flags.Add( vDetail.CloneTyped() );
			}

			foreach ( Derived.FieldDetail vDetail in mFields )
			{
				v_oReturn.Fields.Add( vDetail.CloneTyped() );
			}

			foreach ( Derived.MethodDetail vDetail in mMethods )
			{
				v_oReturn.Methods.Add( vDetail.CloneTyped() );
			}

			foreach ( Derived.PermissionDetail vDetail in mPermissions )
			{
				v_oReturn.Permissions.Add( vDetail.CloneTyped() );
			}

			foreach ( Derived.CollectionDetail vDetail in mCollections )
			{
				v_oReturn.Collections.Add( vDetail.CloneTyped() );
			}

			foreach ( Derived.DataRowDetail vDetail in mInitialData )
			{
				v_oReturn.InitialData.Add( vDetail.CloneTyped() );
			}
			
			return ( v_oReturn );
		}

		public virtual Derived.ObjectDetail CloneTyped()
		{
			return ( ( Derived.ObjectDetail )this.Clone() );
		}
   }
}
   